home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TeX 1995 July
/
TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO
/
dviware
/
dvi2ps
/
dvi-to-ps
/
findfile.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-01
|
10KB
|
318 lines
/* findfile.c */
/* Copyright 1985 Massachusetts Institute of Technology */
/* modified by Peter Damron 1987 University of Washington */
/*---------------------------------------------------------------------*/
#ifndef lint
static char rcsid[] = "$Header: findfile.c,v 2.0 88/06/07 15:02:38 peterd Rel2 $";
#endif lint
/*---------------------------------------------------------------------*/
#include <stdio.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/file.h>
#include <sys/dir.h>
#include "findfile.h"
#ifndef TRUE
#define TRUE -1
#define FALSE 0
#endif TRUE
/* normally defined in <sys/dir.h>, but just to make sure */
#ifndef MAXNAMLEN
#define MAXNAMLEN 255
#endif MAXNAMLEN
/*---------------------------------------------------------------------*/
/* find a font file in a single directory */
/* true if it found the font file, false otherwise */
/* s is the return filename string, if found (e.g. area/stylepoint.maggf */
/* area is directory to look in */
/* style is the font style (e.g. cmr) */
/* point is the design point size of the font */
/* mag is the magnification - adjusted for this dpi and font format */
int
FindFileInDir(area, style, point, mag, s)
char *area,*style,*s;
int point,mag;
{
FILE *f;
char buf[MAXNAMLEN];
int found = 0;
/* presence of file "SUBDIR" means subdirectory per font style */
sprintf(s,"%s/SUBDIR",area);
#ifdef USEPXL
if (!access(s,F_OK)) {
sprintf(s,"%s/%s/%s%d.%dpxl",area,style,style,point,mag);
} else {
sprintf(s,"%s/%s%d.%dpxl",area,style,point,mag);
}
#else not USEPXL
if (!access(s,F_OK)) {
sprintf(s,"%s/%s/%s%d.%dgf",area,style,style,point,mag);
} else {
sprintf(s,"%s/%s%d.%dgf",area,style,point,mag);
}
#endif USEPXL
if (!access(s,R_OK)) {
/* font file is there and we can read it */
return(TRUE);
}
/* font file is not there */
/* try to write out a message to "NEEDED" file */
sprintf(buf,"%s/NEEDED",area);
if (!access(buf,W_OK)) {
#ifdef USEPXL
sprintf(s,"%s%d.%dpxl\n",style,point,mag);
#else not USEPXL
sprintf(s,"%s%d.%dgf\n",style,point,mag);
#endif USEPXL
f = fopen(buf,"r+");
while (fgets(buf,sizeof(buf),f)) {
if (!strcmp(buf,s)) {
found++;
}
}
if (!found) fputs(s,f);
fclose(f);
}
return(FALSE);
}
/*---------------------------------------------------------------------*/
/* find a font file in a directory vector (path) */
/* true if it found a font file, false otherwise */
/* s is the return filename string, if found (e.g. area/stylepoint.maggf */
/* dirvec is a vector of directory strings */
/* dirveclen is the length of dirvec vector */
/* area is the first directory to search */
/* name is the font style and font design size concatenated */
/* mag is the magnification spec - modified for dpi and font format */
/* s is the return filename string */
/* nname is the return name if a substitution is made */
/* nmag is the return magnification if a substitution is made */
int FindFontFile(dirvec,dirveclen,name, mag, s, nname, nmag)
char *dirvec[],*name,*s,*nname;
int dirveclen,mag,*nmag;
{
int i,point;
char style[MAXNAMLEN];
/* default is to use the input name and mag as the output name and mag */
strcpy(nname,name);
*nmag = mag;
/* break the font name into style and design point size */
point = -1;
(void) sscanf(name,"%[^0123456789.]%d",style,&point);
#ifdef NOTDEF
/* should check these values here */
Warning("internal - find font %s style %s point %d mag %d\n",
name,style,point,mag);
#endif NOTDEF
/* First check dir area given in DVI file */
/* Then check along dirvec */
for (i = 0; i < dirveclen; i++) {
if (FindFileInDir(dirvec[i], style, point, mag, s)) {
return(TRUE);
}
}
/* next check for closest magnification along dirvec */
/* note: no check in area here */
return(FindAnyFile(dirvec,dirveclen,style,point,mag,name,s,nname,nmag));
}
/*---------------------------------------------------------------------*/
/* find out how similar two strings are */
/* used to compare font style names */
/* rather an arbitrary measure */
/* e.g. may not have anything to do with how similar two fonts are */
int StrDiff(s1,s2)
char *s1,*s2;
{
register int diff = 0;
while (*s1 && *s2) diff += abs(*s1++ - *s2++);
while (*s1) diff += *s1++;
while (*s2) diff += *s2++;
return(diff);
}
/*---------------------------------------------------------------------*/
/* scan a single directory for the best font file */
ScanDir(dir,
style,point,mag,
beststyle,bestname,bestpoint,bestmag,
min_ds,min_dpm,min_dp)
char *dir,*style,*beststyle,*bestname;
int point,mag,*bestpoint,*bestmag,*min_ds,*min_dpm,*min_dp;
{
DIR *dirstream; /* stream of file records in this dir */
register struct direct *dirrecord; /* pointer to a file record */
char qstyle[MAXNAMLEN]; /* style name of current file */
int qpoint; /* point size of current file */
int qmag; /* mag size of current file */
register int ds; /* local delta in style */
register int dpm; /* local delta in point*mag */
register int dp; /* local delta in point */
/* go through the files in this directory */
if (dirstream = opendir(dir)) {
while (dirrecord = readdir(dirstream)) {
#ifdef USEPXL
/* only use *pxl files */
if (!strcmp(dirrecord->d_name+dirrecord->d_namlen-3,"pxl")) {
#else not USEPXL
/* only use *gf files */
if (!strcmp(dirrecord->d_name+dirrecord->d_namlen-2,"gf")) {
#endif USEPXL
/* parse the filename into style, point, mag */
qpoint = -1; qmag = -1;
(void) sscanf(dirrecord->d_name,"%[^0123456789.]%d.%d",
qstyle,&qpoint,&qmag);
/* compute differences */
ds = StrDiff(style,qstyle);
dpm = abs((point*mag) - (qpoint*qmag));
dp = abs(point - qpoint);
#ifdef NOTDEF
dm = abs(mag - qmag);
#endif NOTDEF
/* check for a better font than before */
if ((ds < *min_ds)
|| (ds == *min_ds && dpm <= *min_dpm)
|| (ds == *min_ds && dpm == *min_dpm && dp <= *min_dp)) {
sprintf(bestname,"%s/%s",dir,dirrecord->d_name);
strcpy(beststyle,qstyle);
*bestpoint = qpoint;
*bestmag = qmag;
*min_ds = ds;
*min_dpm = dpm;
*min_dp = dp;
}
}
}
closedir(dirstream);
}
}
/*---------------------------------------------------------------------*/
/* scan a font sub-directory tree for the best font file */
ScanTree(dir,name,
style,point,mag,
beststyle,bestname,bestpoint,bestmag,
min_ds,min_dpm,min_dp)
char *dir,*name,*style,*beststyle,*bestname;
int point,mag,*bestpoint,*bestmag,*min_ds,*min_dpm,*min_dp;
{
DIR *dirstream;
struct direct *dirrecord;
int ds;
char pdir[MAXNAMLEN];
if (dirstream = opendir(dir)) {
while (dirrecord = readdir(dirstream)) {
if (dirrecord->d_name[0] != '.') {
ds = StrDiff(name,dirrecord->d_name);
if (ds <= *min_ds) {
sprintf(pdir,"%s/%s",dir,dirrecord->d_name);
/* try this sub-directory */
ScanDir(pdir,
style,point,mag,
beststyle,bestname,bestpoint,bestmag,
min_ds,min_dpm,min_dp);
/* we should update min_ds at this point */
/* but we rely on ScanDir to do that */
}
}
}
closedir(dirstream);
}
}
/*---------------------------------------------------------------------*/
/* finds the best match to the desired font */
/* searches through directory vector (path) */
/* best in what sense ??? */
int FindAnyFile(dirvec,dirveclen,style,point,mag,name,s,nname,nmag)
char *dirvec[],*style,*name,*s,*nname;
int dirveclen,point,mag,*nmag;
{
char foo[MAXNAMLEN]; /* temp file name string */
char bestname[MAXNAMLEN]; /* best font file name string */
char beststyle[MAXNAMLEN]; /* best font style name string */
int i; /* temp index into directory vector */
int bestpoint; /* best font point size */
int bestmag; /* best font magnification size */
int min_ds; /* minimum delta found in font sytle name string */
int min_dpm; /* minimum delta found in font point*mag */
int min_dp; /* minimum delta found in font point */
bestname[0] = '\0';
min_ds = min_dpm = min_dp = 9999999;
for (i = 0; i < dirveclen; i++) {
/* check for font sub-directory tree (not flat) */
sprintf(foo,"%s/SUBDIR",dirvec[i]);
if (!access(foo,F_OK)) {
ScanTree(dirvec[i],name,
style,point,mag,
beststyle,bestname,&bestpoint,&bestmag,
&min_ds,&min_dpm,&min_dp);
} else {
ScanDir(dirvec[i],
style,point,mag,
beststyle,bestname,&bestpoint,&bestmag,
&min_ds,&min_dpm,&min_dp);
}
}
if (bestname[0]) {
/* well we found something that looks ok */
/* get return values: s, nname, nmag */
if (bestpoint > 0) {
sprintf(nname,"%s%d",beststyle,bestpoint);
} else {
/* does this ever get used? this looks bad */
strcpy(nname,beststyle);
}
*nmag = bestmag;
strcpy(s,bestname);
/* issue a warning if we are doing a substitution */
if ((strcmp(beststyle,style)
|| bestpoint != point || abs(bestmag - mag) > 2)) {
#ifdef NOTDEF
Warning("Substituted font %s at mag %d for %s at mag %d\n",
nname,(bestmag * 4 + 3) / 6,
name,(mag * 4 + 3) / 6);
/* is this message very useful? */
/* why the magic numbers? */
/* this message could be better */
Warning("Substituted font %s at mag %d for %s at mag %d\n",
nname,bestmag,name,mag);
#endif NOTDEF
#ifdef USEPXL
Warning("Substituted font %s%d.%dpxl -> %s\n",style,point,mag,s);
#else not USEPXL
Warning("Substituted font %s%d.%dgf -> %s\n",style,point,mag,s);
#endif USEPXL
}
return(TRUE);
}
return(FALSE);
}
/*---------------------------------------------------------------------*/